﻿using System.IO.Compression;

namespace PluginCreaterPackgeTool
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var solutionPath = args[0];
            Console.WriteLine("solutionPath: " + solutionPath);

            var guid = Guid.NewGuid().ToString();
            var targetPath = Path.Combine(solutionPath, guid);
            try
            {
                Directory.CreateDirectory(targetPath);
                CopyFolder(
                    Path.Combine(solutionPath, "bin"),
                    Path.Combine(targetPath, "bin"),
                    new string[] { ".pdb" },
                    null
                    );
                CopyFolder
                    (Path.Combine(solutionPath, "ForguncyPluginTemplate"),
                    Path.Combine(targetPath, "ForguncyPluginTemplate"),
                    null,
                    new string[] { "bin", ".vs", "obj" });

                var targetZip = Path.Combine(solutionPath, "forguncyPluginBuilder_V10.zip");
                if (File.Exists(targetZip))
                {
                    File.Delete(targetZip);
                }
                ZipFile.CreateFromDirectory(targetPath, targetZip);
            }
            finally
            {
                Directory.Delete(targetPath, true);
            }
        }
        public static void CopyFolder(string sPath, string dPath,
            Func<string, bool, bool> filter)
        {
            if (!Directory.Exists(sPath))
            {
                return;
            }

            // 创建目的文件夹                  
            if (!Directory.Exists(dPath))
            {
                Directory.CreateDirectory(dPath);
            }

            var files = GetFiles(sPath);
            Parallel.ForEach(files, file =>
            {
                FileInfo srcFileInfo;
                FileInfo targetFileInfo;

                var sourceFileFullName = file;
                var targetFileFullName = dPath + Path.DirectorySeparatorChar + Path.GetFileName(file);
                if (filter != null && !filter(file, true))
                {
                    return;
                }

                var targetExist = File.Exists(targetFileFullName);
                if (targetExist)
                {
                    srcFileInfo = new FileInfo(sourceFileFullName);
                    targetFileInfo = new FileInfo(targetFileFullName);
                }

                try
                {
                    // if target file exists and is readonly.the CopyTo method will throw a unauthorizedexception
                    File.Copy(file, targetFileFullName, true);
                }
                catch
                {
                    // Try again? 有的时候拷贝文件会崩，但是，手工按一下F5就好了，这里尝试再拷贝一次来绕这个Bug，没想到别的好的方案。权且一试，
                    // 等找的好方案或者不能修复这个问题在看， 胡森
                    File.Copy(file, targetFileFullName, true);
                }
            });

            // 循环子文件夹
            string[] subDirArray = Directory.GetDirectories(sPath);
            foreach (string subDir in subDirArray)
            {
                if (filter != null && !filter(subDir, false))
                {
                    continue;
                }

                CopyFolder(subDir, dPath + Path.DirectorySeparatorChar + Path.GetFileName(subDir), filter);
            }
        }
        static string[] GetFiles(string path)
        {
            try
            {
                return Directory.GetFiles(path);
            }
            catch
            {
                return new string[0];
            }
        }
        public static void CopyFolder(string sPath, string dPath)
        {
            CopyFolder(sPath, dPath, null);
        }

        public static void CopyFolder(string sPath, string dPath, string[] ignoreFiles, string[] ignoreDirs)
        {
            CopyFolder(sPath, dPath, (path, isFile) =>
            {
                if (isFile)
                {
                    if (ignoreFiles != null)
                    {
                        if (IsMatchIgnoreFile(ignoreFiles, path))
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    if (ignoreDirs != null)
                    {
                        if (ignoreDirs.Contains(Path.GetFileName(path)))
                        {
                            return false;
                        }
                    }
                }

                return true;
            });
        }

        private static bool IsMatchIgnoreFile(string[] ignoreFiles, string file)
        {
            if (ignoreFiles == null)
            {
                return false;
            }

            foreach (var ignoreFile in ignoreFiles)
            {
                var fileName = Path.GetFileName(file).ToLower();
                var condition = ignoreFile.ToLower();
                if (condition.StartsWith("."))
                {
                    if (fileName.EndsWith(condition))
                    {
                        return true;
                    }
                }
                else
                {
                    if (fileName == condition)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}